home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Communications / pcomm / Source / x_extrnl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-12  |  2.3 KB  |  115 lines

  1. /*
  2.  * Spawn a shell with the stdin and stdout swapped with the remote
  3.  * system, ie:
  4.  *                               +----------+
  5.  *    TTYin ------------> stdin  |          |
  6.  *                               |  shell   |
  7.  *    TTYout <---------- stdout  |          |
  8.  *                               +----------+
  9.  *
  10.  * An undocumented feature:  The external protocol gateway
  11.  * can be used to pipe the output of a normal Unix command to the
  12.  * remote system.
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <signal.h>
  17. #include <curses.h>
  18. #include <errno.h>
  19. #include "config.h"
  20.  
  21. #ifdef BSD
  22. #ifndef SIGCLD
  23. #define SIGCLD SIGCHLD
  24. #endif /* SIGCLD */
  25. #include <sys/file.h>
  26. #else /* BSD */
  27. #include <fcntl.h>
  28. #endif /* BSD */
  29.  
  30. void
  31. do_extrnl(cmd)
  32. char *cmd;
  33. {
  34.     extern int fd, errno;
  35.     WINDOW *xt_win, *newwin();
  36.     SIG_TYPE (*istat)(), (*qstat)(), (*cstat)();
  37.     int epid, want_out;
  38.     unsigned int sleep();
  39.     void _exit(), input_off();
  40.  
  41.     input_off();
  42.                     /* a full window */
  43.     xt_win = newwin(LINES, COLS, 0, 0);
  44.     nl();
  45.     touchwin(xt_win);
  46.     wrefresh(xt_win);
  47.  
  48.     if (!(epid = fork())) {
  49.                     /* create a new process group ID */
  50. #ifdef BSD
  51.         setpgrp(0, getpid());
  52. #else /* BSD */
  53.         setpgrp();
  54. #endif /* BSD */
  55.                     /* swap the stdin */
  56.         close(0);
  57.         dup(fd);
  58.                     /* swap the stdout */
  59.         close(1);
  60.         dup(fd);
  61. #ifdef SETUGID
  62.         setgid(getgid());
  63.         setuid(getuid());
  64. #endif /* SETUGID */
  65.         execl("/bin/sh", "sh", "-c", cmd, (char *) 0);
  66.         _exit(1);
  67.     }
  68.     istat = signal(SIGINT, SIG_IGN);
  69.     qstat = signal(SIGQUIT, SIG_IGN);
  70.     cstat = signal(SIGCLD, SIG_IGN);
  71.  
  72.     /*
  73.      * Check the keyboard while the external program is running.  If
  74.      * the user hits the <ESC> key, then kill the entire process
  75.      * group associated with the new shell.
  76.      */
  77.     want_out = 0;
  78.     while(1) {
  79.         switch(wait_key(stdscr, 1)) {
  80.             case -1:    /* timed out */
  81.                 break;
  82.             case 27:    /* a user abort */
  83. #ifdef BSD
  84.                 killpg(epid, SIGKILL);
  85. #else /* BSD */
  86.                 kill(-epid, SIGKILL);
  87. #endif /* BSD */
  88.                 want_out++;
  89.                 break;
  90.             default:
  91.                 beep();
  92.                 break;
  93.         }
  94.         if (want_out)
  95.             break;
  96.                     /* see if the process it still active */
  97.         if ((kill(epid, 0) == -1) && errno == ESRCH) 
  98.             break;
  99.     }
  100.  
  101.     signal(SIGINT, istat);
  102.     signal(SIGQUIT, qstat);
  103.     signal(SIGCLD, cstat);
  104.                     /* the tty may have been clobbered */
  105.     sleep(1);
  106.     fixterm();
  107.     nonl();
  108.  
  109.     clearok(curscr, TRUE);
  110.     werase(xt_win);
  111.     wrefresh(xt_win);
  112.     delwin(xt_win);
  113.     return;
  114. }
  115.